﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using ElectronicCommerce.Framework.Web.Configuration;
using ElectronicCommerce.Framework.Web.Configuration.Resource;
using ElectronicCommerce.Framework.Web.ResourceManagement;

namespace ElectronicCommerce.Framework.Web.Mvc.WebForm
{
    public abstract class CustomViewPageBase<TCustomContext> : System.Web.UI.Page
        where TCustomContext : CustomContextBase
    {
        private MetadataCollection _metadata = new MetadataCollection();

        public CustomViewPageBase()
        {
            CustomContext = Activator.CreateInstance<TCustomContext>();
            Url = new UrlBuilder();
            Resource = new ResourceBuilder();
        }

        #region 基础页属性
        internal Enum InternalViewPageAlias { get; set; }

        /// <summary>
        /// SEO 避免重复页面标题，自动添加页面路径
        /// </summary>
        public virtual bool AvoidDuplicatedTitle
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// HTML 页面 HEAD 中 Meta 标记内容
        /// </summary>
        public MetadataCollection Metadata
        {
            get { return _metadata; }
        }

        /// <summary>
        /// 页面上下文
        /// </summary>
        public TCustomContext CustomContext { get; private set; }

        /// <summary>
        /// 页面链接生成器
        /// </summary>
        public UrlBuilder Url { get; private set; }

        /// <summary>
        /// 资源文件生成器
        /// </summary>
        public ResourceBuilder Resource { get; private set; }

        /// <summary>
        /// 显示页面数据集
        /// </summary>
        public virtual CustomModelContainer<TCustomContext> Model { get; protected set; }

        /// <summary>
        /// 页面控制器
        /// </summary>
        public CustomControllerBase Controller { get; set; }
        #endregion

        /// <summary>
        /// 构建 SEO Canonical 链接地址
        /// </summary>
        /// <param name="url"></param>
        /// <returns>MetaLink 对象</returns>
        public MetadataLink GetCanonicalLink(string url)
        {
            return new MetadataLink()
            {
                Rel = "canonical",
                Href = url,
            };
        }

        public void SetCanonicalLink(string url)
        {
            Metadata.CanonicalLink = GetCanonicalLink(url);
        }

        #region 页面事件流程
        protected override void OnPreInit(EventArgs e)
        {
            //Render SERVER ID
            CustomContext.Response.AddHeader("X-Who", System.Net.Dns.GetHostName());

            if (!string.IsNullOrEmpty(Controller.MasterPageFile))
            {
                MasterPageFile = Controller.MasterPageFile;
            }

            Model = new CustomModelContainer<TCustomContext>(CustomContext, Controller.Models);

            base.OnPreInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            RenderPage();

            base.OnPreRender(e);
        }

        /// <summary>
        /// 生成显示页面 HTML 事件
        /// </summary>
        protected virtual void RenderPage()
        {
            //Rendering Page
        }
        #endregion
    }

    public abstract class CustomViewPageBase<
        TController,
        TModel,
        TCustomViewMasterPage,
        TCustomContext,
        TPageAliasType> : CustomViewPageBase<TCustomContext>
        where TController : CustomControllerBase
        where TModel : CustomModelBase
        where TCustomViewMasterPage : MasterPage
        where TCustomContext : CustomContextBase
        where TPageAliasType : struct
    {
        private List<Enum> _csses = new List<Enum>();
        private List<Enum> _scripts = new List<Enum>();
        private List<string> _inlineStyles = new List<string>();
        private List<string> _inlineScripts = new List<string>();

        private CustomModelContainer<TCustomContext, TModel> _model = null;

        public abstract TPageAliasType ViewPageAlias { get; }

        new public CustomModelContainer<TCustomContext, TModel> Model
        {
            get
            {
                if (_model == null)
                {
                    _model = new CustomModelContainer<TCustomContext, TModel>(CustomContext, base.Model.ModelDictionary);
                }

                return _model;
            }
        }

        protected override void OnPreInit(EventArgs e)
        {
            base.InternalViewPageAlias = ViewPageAlias as Enum;

            TController controller = Activator.CreateInstance<TController>();
            controller.CustomContext = CustomContext;
            controller.ViewPage = this;

            Controller = controller;

            base.OnPreInit(e);
        }

        protected override void RenderPage()
        {
            RenderMetadata();

            base.RenderPage();
        }

        new public TController Controller
        {
            get { return base.Controller as TController; }
            set { base.Controller = value; }
        }

        /// <summary>
        /// 添加 CSS
        /// </summary>
        /// <param name="alias"></param>
        protected void AddCss(Enum alias)
        {
            _csses.Add(alias);

        }

        /// <summary>
        /// 添加 Inline Style
        /// </summary>
        /// <param name="styles"></param>
        protected void AddStyles(string styles)
        {
            _inlineStyles.Add(styles);
        }

        /// <summary>
        /// 添加 Javascript 文件
        /// </summary>
        /// <param name="alias"></param>
        protected void AddJavascript(Enum alias)
        {
            _scripts.Add(alias);
        }

        /// <summary>
        /// 添加 Inline Scripts，在页面 HTML HEAD 中输出
        /// </summary>
        /// <param name="scripts"></param>
        protected void AddJavascript(string scripts)
        {
            _inlineScripts.Add(scripts);
        }

        /// <summary>
        /// Render Metadata on echa Page ( RenderPage Event )
        /// </summary>
        protected void RenderMetadata()
        {
            #region css
            _csses.Reverse();
            foreach (Enum alias in _csses)
            {
                string url = Resource.BuildCss(alias);

                if (!string.IsNullOrEmpty(url))
                {
                    Metadata.Css.Insert(url);
                }
            }
            _csses.Clear();
            #endregion

            #region style
            _inlineStyles.Reverse();
            foreach (string s in _inlineStyles)
            {
                Metadata.InlineStyles.Insert(0, s);
            }
            _inlineStyles.Clear();
            #endregion

            #region script
            _scripts.Reverse();
            foreach (Enum alias in _scripts)
            {
                string url = Resource.BuildJs(alias);

                if (!string.IsNullOrEmpty(url))
                {
                    Javascript js = ConfigHelper.JavascriptConfig.GetJavascript(alias.ToString());

                    Metadata.Scripts.Insert(url, js.InHtmlHead);
                }
            }
            _scripts.Clear();
            #endregion

            #region inlineScripts
            _inlineScripts.Reverse();
            foreach (string s in _inlineScripts)
            {
                Metadata.InlineScripts.Insert(0, s);
            }
            _inlineScripts.Clear();
            #endregion
        }
    }
}
